package interfaces.hud;

import fileHandling.language.LanguageLoader;
import fileHandling.language.interfaces.HUDText;
import gameStates.absGamesStates.AbsIngameState;
import gameStates.absGamesStates.gui.AbsHUDState;
import interfaces.GUISource;
import interfaces.hud.chat.ChatType;
import interfaces.hud.pilot.KillInfoContent;
import interfaces.hud.pilot.status.CounterMeasureHUD;
import interfaces.hud.pilot.status.HunterStatusHUD;
import interfaces.superWidgets.InterfaceContainer;
import interfaces.superWidgets.InterfaceElement;
import interfaces.superWidgets.InterfaceLabel;
import interfaces.superWidgets.InterfaceWindow;
import interfaces.superWidgets.FlowContent;
import interfaces.superWidgets.StaticContent;
import interfaces.superWidgets.UpdateWidget;

import java.util.ArrayList;
import java.util.List;

import logic.common.game.Game;
import logic.common.player.Player;
import logic.common.team.Team;
import logic.common.team.teamListeners.ShipAddedEvent;
import logic.common.team.teamListeners.ShipRemovedEvent;
import logic.common.team.teamListeners.TeamShipListener;
import logic.ships.frigate.Frigate;
import logic.weapons.Weapon;

import org.fenggui.IWidget;
import org.fenggui.StandardWidget;
import org.fenggui.binding.render.ImageFont;
import org.fenggui.decorator.background.PlainBackground;
import org.fenggui.util.Color;

import com.jme.scene.Node;

public class BasicHUD extends InterfaceElement implements AbsHUD {
	
	protected Game game;
	protected AbsIngameState ingameState;
	
	protected Node rootNode;
	protected List<UpdateWidget> updateWidgets;
	protected InterfaceContainer basicContent;
	
	protected KillInfoContent killInfoContent;
	protected FlowContent chatContent, killContent;
	protected CounterMeasureHUD counterMeasureHUD;
	protected GameTimeWindow gameHUD;
	protected StandardWidget topHUDElement;
	protected HunterStatusHUD hunterStatusHUD;
	
	protected EventLabel eventLabel;
	
	protected int windowHeight;
	
	protected boolean isInitialized;
	
	public BasicHUD(AbsHUDState hudState) {
		super(hudState);
		
		windowHeight = getHeight() / 10 * 3;
		
		rootNode = new Node("HUD RootNode");
		
		updateWidgets = new ArrayList<UpdateWidget>();
		basicContent = new StaticContent(getWidth(), getHeight(), 0, 0);
		
		ingameState = hudState.getIngameState();
		
		game = ingameState.getGame();
		
		gameHUD = new GameTimeWindow(this);
		addWidget(gameHUD);
		
		topHUDElement = game.getGameSetup().getTopHUDElement(this);
		addWidget(topHUDElement);
		
		hunterStatusHUD = new HunterStatusHUD(this);
		
		int disWidth = getWidth();
		int cmX = hunterStatusHUD.getX() + hunterStatusHUD.getWidth();
		int cmWidth = disWidth - cmX - disWidth / 5;
		int cmHeight = getHeight() / 20;
		Player p = hudState.getIngameState().getPlayer();
		counterMeasureHUD = new CounterMeasureHUD(cmWidth, cmHeight, cmX, 0, p, this);
		
		initChat();
		
		eventLabel = new EventLabel(GUISource.middleFont);
		addWidget(eventLabel);
		
		addTeamListeners(game.getTeamA());
		addTeamListeners(game.getTeamB());
	}
	
	private void addTeamListeners(Team team) {
		addListener(team, new TeamShipListener() {
			@Override
			public void shipRemoved(ShipRemovedEvent event) {
				if(event.getShip() instanceof Frigate) {
					String frigateOf = LanguageLoader.get(HUDText.Frigate_of_Team);
					String fraction = event.getTeam().getFraction().toString();
					String destr = LanguageLoader.get(HUDText.destroyed);
					String text = frigateOf + " " + fraction + " " + destr;
					showEventText(text, ingameState.getPlayer().getTeam() == event.getTeam());
				}
			}
			
			@Override
			public void shipAdded(ShipAddedEvent event) {
				if(event.getShip() instanceof Frigate) {
					String newFrigate = LanguageLoader.get(HUDText.New_Frigate_for_Team);
					String fraction = event.getTeam().getFraction().toString();
					String text = newFrigate + " " + fraction;
					showEventText(text, ingameState.getPlayer().getTeam() == event.getTeam());
				}
			}
		});
	}
	
	public int getWindowHeight() { return windowHeight; }
	
	protected void initChat() {
		int width = getWidth() / 4;
		int height = getHeight() / 3;
		int y = gameHUD.getY() + gameHUD.getHeight();
		int labelHeight = height / 8;
		
		chatContent = new FlowContent(width, height, 0, y, labelHeight);
		chatContent.getAppearance().add(new PlainBackground(Color.TRANSPARENT));
		addWidget(chatContent);
		
		height -= (GUISource.middleFont.getHeight() / 3 * 4);
		killContent = new FlowContent(width, height, getWidth() - width, y, labelHeight);
		killContent.getAppearance().add(new PlainBackground(Color.TRANSPARENT));
		addWidget(killContent);
	}
		
	@Override
	public void addWidget(IWidget widget) {
		if(widget instanceof UpdateWidget) updateWidgets.add((UpdateWidget)widget);
		
		basicContent.addWidget(widget);
		if(widget instanceof InterfaceWindow) {
			guiState.getGUIDisplay().addWidget(basicContent);
			((InterfaceWindow)widget).addToContainer(basicContent);
			guiState.getGUIDisplay().removeWidget(basicContent);
		}
	}
	
	@Override
	public void removeWidget(IWidget widget) {
		updateWidgets.remove(widget);
		
		basicContent.removeWidget(widget);
	}
	
	public void clean() {
		rootNode.detachAllChildren();
	}
	
	@Override
	public void updateMoney(int newMoney) {
		gameHUD.updateMoney(newMoney);
	}
	
	public void addToKillContent(Player killer, Player victim, Weapon weapon) {
		int height = killContent.getHeight();
		int width = killContent.getWidth();
		int labelWidth = width / 3;
		ImageFont font = GUISource.smallestFont;
		
		StaticContent content = new StaticContent(width, height, 0, 0);
		
		InterfaceLabel killerLabel = createNewLabel(killer, 0);
		GUISource.setFont(killerLabel, font);
		killerLabel.setSize(labelWidth, height);
		content.addWidget(killerLabel);
		
		InterfaceLabel weaponLabel = new InterfaceLabel(weapon.getName(), font);
		GUISource.setTextColor(weaponLabel, Color.WHITE);
		weaponLabel.setXY(labelWidth, 0);
		weaponLabel.setSize(labelWidth, height);
		content.addWidget(weaponLabel);
		
		InterfaceLabel victimLabel = createNewLabel(victim, 2 * labelWidth);
		GUISource.setFont(victimLabel, font);
		victimLabel.setSize(labelWidth, height);
		content.addWidget(victimLabel);
		
		killContent.addFlowWidget(content);
	}
	
	protected InterfaceLabel createNewLabel(Player player, int x) {
		InterfaceLabel killerLabel = new InterfaceLabel(player.getName(), GUISource.smallFont);
		GUISource.setTextColor(killerLabel, getKillColor(player));
		killerLabel.setXY(x, 0);
		return killerLabel;
	}
	
	protected Color getKillColor(Player player) {
		Player currentPlayer = ingameState.getPlayer();
		if(player.isTeamMate(currentPlayer)) return Color.LIGHT_BLUE;
		return Color.LIGHT_RED;
	}
		
	public Node getRootNode() { return rootNode; }
		
	public List<UpdateWidget> getUpdateWidgets() { return updateWidgets; }
	
	public InterfaceContainer getBasicContent() { return basicContent; }
	
	public AbsIngameState getIngameState() { return ingameState; }

	public StandardWidget getTopHUDElement() { return topHUDElement; }
	
	public GameTimeWindow getGameTimeWindow() { return gameHUD; }
	
	@Override
	public AbsHUDState getHUDState() { return (AbsHUDState)guiState; }
	
	public void showChatText(String text, ChatType type) {
		Color color = null;
		switch(type) {
			case Chat : color = Color.WHITE; break;
			case TeamChat : color = Color.LIGHT_BLUE; break;
			case SquadChat : color = Color.LIGHT_GREEN; break;
		}
		chatContent.addText(text, color, GUISource.middleFont);
	}
	
	public void showEventText(String text, boolean goodEvent) {
		eventLabel.showText(text, goodEvent);
	}
}